<template>
  <div class="max-w-[1920px] mx-auto px-4">
    <div class="flex gap-8">
      <!-- 相关文章列表 -->
      <aside class="hidden xl:block w-64 flex-shrink-0">
        <div
          class="sticky top-6 bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6 border border-gray-100 dark:border-gray-700"
        >
          <h3
            class="text-lg font-semibold mb-4 text-gray-900 dark:text-white flex items-center"
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              class="h-5 w-5 mr-2"
              viewBox="0 0 20 20"
              fill="currentColor"
            >
              <path
                fill-rule="evenodd"
                d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"
                clip-rule="evenodd"
              />
            </svg>
            相关文章
          </h3>
          <nav class="space-y-2">
            <NuxtLink
              v-for="relatedPost in relatedPosts"
              :key="relatedPost.path"
              :to="relatedPost.path"
              class="block p-3 rounded-md transition-colors duration-200"
              :class="{
                'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400':
                  relatedPost.path === route.path,
                'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700':
                  relatedPost.path !== route.path,
              }"
            >
              <h4 class="font-medium mb-1 line-clamp-1">
                {{ relatedPost.title }}
              </h4>
              <p class="text-sm text-gray-500 dark:text-gray-500 line-clamp-2">
                {{ relatedPost.description }}
              </p>
            </NuxtLink>
          </nav>
        </div>
      </aside>

      <!-- 文章内容 -->
      <div class="flex-grow max-w-3xl mx-auto">
        <!-- 加载状态 -->
        <div v-if="pending" class="text-center py-8">
          <div
            class="animate-spin rounded-full h-12 w-12 border-b-2 border-gray-900 mx-auto"
          ></div>
          <p class="mt-4 text-gray-600">加载中...</p>
        </div>

        <!-- 错误状态 -->
        <div v-else-if="error" class="text-center py-8">
          <p class="text-red-500">加载文章时发生错误</p>
          <button
            @click="refresh"
            class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
          >
            重试
          </button>
        </div>

        <!-- 文章内容 -->
        <article v-else-if="post" class="prose prose-lg max-w-none">
          <div id="articleContainer">
            <h1 class="text-3xl font-bold mb-4">{{ post.title }}</h1>
            <div class="text-gray-500 mb-8">
              <time :datetime="post.date">{{
                new Date(post.date).toLocaleDateString("zh-CN")
              }}</time>
            </div>
            <ContentRenderer :value="post" />
          </div>
        </article>

        <!-- 文章不存在 -->
        <div v-else class="text-center py-8">
          <p class="text-gray-600">文章不存在</p>
          <NuxtLink
            to="/blog"
            class="mt-4 inline-block px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
          >
            返回博客列表
          </NuxtLink>
        </div>
      </div>

      <!-- 文章目录 -->
      <aside class="hidden xl:block w-72 flex-shrink-0">
        <div
          class="sticky top-6 bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6 border border-gray-100 dark:border-gray-700"
        >
          <h3
            class="text-lg font-semibold mb-4 text-gray-900 dark:text-white flex items-center"
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              class="h-5 w-5 mr-2"
              viewBox="0 0 20 20"
              fill="currentColor"
            >
              <path
                fill-rule="evenodd"
                d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"
                clip-rule="evenodd"
              />
            </svg>
            文章目录
          </h3>
          <nav
            class="space-y-1.5 max-h-[calc(100vh-12rem)] overflow-y-auto pr-2"
          >
            <a
              v-for="item in toc"
              :key="item.id"
              :href="`#${item.id}`"
              @click.prevent="scrollToHeading(item.id)"
              class="block text-sm py-1.5 px-3 rounded-md transition-colors duration-200"
              :class="{
                'pl-6': item.level === 3,
                'pl-4': item.level === 2,
                'pl-2': item.level === 1,
                'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700': true,
                'font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20':
                  isActiveHeading(item.id),
              }"
            >
              {{ item.text }}
            </a>
          </nav>
        </div>
      </aside>
    </div>
  </div>
</template>

<script setup>
const route = useRoute();
const slug = route.params.slug;

// 获取博客文章数据
const {
  data: post,
  pending,
  error,
} = await useAsyncData(`blog-${slug}`, () => {
  return queryCollection("blog").path(`/blog/${slug}`).first();
});

// 获取相关文章列表
const { data: relatedPosts } = await useAsyncData("related-posts", () => {
  return queryCollection("blog").all();
});

// 设置页面标题
useHead({
  title: post.value?.title || "博客文章",
  meta: [
    {
      name: "description",
      content: post.value?.description || "博客文章详情",
    },
  ],
});

// 处理目录
const toc = ref([]);
const activeHeading = ref("");

// 更新目录
const updateToc = () => {
  if (process.client) {
    // 只获取文章内容区域内的标题
    const articleContainer = document.querySelector("#articleContainer");
    if (!articleContainer) return;

    const headings = articleContainer.querySelectorAll("h1, h2, h3");
    toc.value = Array.from(headings).map((heading) => {
      // 如果没有 id，生成一个
      if (!heading.id) {
        heading.id = heading.textContent.toLowerCase().replace(/\s+/g, "-");
      }
      return {
        id: heading.id,
        text: heading.textContent,
        level: parseInt(heading.tagName.charAt(1)),
      };
    });
  }
};

// 检查标题是否在视口中
const isHeadingInViewport = (element) => {
  const rect = element.getBoundingClientRect();
  return rect.top >= 0 && rect.top <= window.innerHeight / 2;
};

// 更新当前活动标题
const updateActiveHeading = () => {
  const articleContainer = document.querySelector("#articleContainer");
  if (!articleContainer) return;

  const headings = articleContainer.querySelectorAll("h1, h2, h3");
  for (const heading of headings) {
    if (isHeadingInViewport(heading)) {
      activeHeading.value = heading.id;
      break;
    }
  }
};

// 检查标题是否处于活动状态
const isActiveHeading = (id) => {
  return activeHeading.value === id;
};

// 滚动到指定标题
const scrollToHeading = (id) => {
  const element = document.getElementById(id);
  if (element) {
    element.scrollIntoView({ behavior: "smooth" });
    activeHeading.value = id;
  }
};

// 监听内容变化，更新目录
watch(
  () => post.value,
  async () => {
    // 等待内容渲染完成
    await nextTick();
    // 给内容渲染一个短暂的延迟
    setTimeout(() => {
      updateToc();
    }, 100);
  },
  { immediate: true }
);

// 监听路由变化
watch(
  () => route.params.slug,
  async () => {
    // 清空当前目录
    toc.value = [];
    activeHeading.value = "";
    // 等待内容渲染完成
    await nextTick();
    // 给内容渲染一个短暂的延迟
    setTimeout(() => {
      updateToc();
    }, 100);
  }
);

// 监听滚动事件
onMounted(() => {
  if (process.client) {
    window.addEventListener("scroll", updateActiveHeading);
  }
});

onUnmounted(() => {
  if (process.client) {
    window.removeEventListener("scroll", updateActiveHeading);
  }
});

// 添加响应式控制
const showSidebars = ref(true);

// 监听窗口大小变化
onMounted(() => {
  if (process.client) {
    const checkScreenSize = () => {
      showSidebars.value = window.innerWidth >= 1280; // xl breakpoint
    };

    window.addEventListener("resize", checkScreenSize);
    checkScreenSize(); // 初始化检查

    return () => {
      window.removeEventListener("resize", checkScreenSize);
    };
  }
});
</script>

<style>
.prose {
  @apply text-gray-800;
}

.prose h1 {
  @apply text-3xl font-bold mb-4 scroll-mt-20;
}

.prose h2 {
  @apply text-2xl font-bold mb-3 mt-6 scroll-mt-20;
}

.prose h3 {
  @apply text-xl font-bold mb-3 mt-6 scroll-mt-20;
}

.prose p {
  @apply mb-4 leading-relaxed;
}

.prose img {
  @apply rounded-lg my-6;
}

.prose a {
  @apply text-blue-600 hover:text-blue-800;
}

.prose code {
  @apply bg-gray-100 px-1 py-0.5 rounded;
}

.prose pre {
  @apply bg-gray-100 p-4 rounded-lg overflow-x-auto;
}

/* 目录样式 */
.sticky {
  position: sticky;
  top: 1.5rem;
}

/* 自定义滚动条样式 */
nav::-webkit-scrollbar {
  width: 4px;
}

nav::-webkit-scrollbar-track {
  @apply bg-transparent;
}

nav::-webkit-scrollbar-thumb {
  @apply bg-gray-300 dark:bg-gray-600 rounded-full;
}

nav::-webkit-scrollbar-thumb:hover {
  @apply bg-gray-400 dark:bg-gray-500;
}

.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 添加响应式样式 */
@media (max-width: 1279px) {
  .prose {
    @apply max-w-none;
  }
}

@media (min-width: 1280px) {
  .prose {
    @apply max-w-3xl;
  }
}
</style>
